unit Item;

interface

uses Engine, DGLE, DGLE_Types, Entity;

const
  ITEM_AMP = 3;

  ItemFName: array [0..ITEMS_COUNT - 1] of AnsiString = (
  'Shield.png', 'WShield.png', 'TShield.png', 'Dirk.png', 'Iceball.png'
  );

type
  TItem = class(TEntity)
  private
    Angle: Integer;
    Dir: Boolean;
    Top: Real;
    Left: Integer;
    FActive: Boolean;
    procedure SetActive(const Value: Boolean);
  public
    constructor Create(X, Y, ID: Integer);
    destructor Destroy; override;
    property Active: Boolean read FActive write SetActive;
  end;

type
  TIBase = class(TObject)
  private

  public
    constructor Create;
    destructor Destroy; override;
    function Count: Integer;
  end;

type
  TAItem = array of TItem;

type
  TItems = class(TObject)
  private
    FItem: TAItem;
    FBase: TIBase;
    procedure SetItem(const Value: TAItem);
    procedure SetBase(const Value: TIBase);
  public
    constructor Create;
    destructor Destroy; override;
    property Base: TIBase read FBase write SetBase;
    property Item: TAItem read FItem write SetItem;
    procedure Add(X, Y, ID: Integer);
    function Count: Integer;
    procedure RenderItem(X, Y, I: Integer);
    procedure Render();
    procedure Update();
  end;

implementation

uses SysUtils, Tile;

{ TItem }

constructor TItem.Create(X, Y, ID: Integer);
begin
  inherited Create(X, Y, ID, 'Resources\Sprites\Items\' + ItemFName[ID], pResMan);
  Self.Active := True;
  Self.Dir := True;
  Self.Top := Rand(-ITEM_AMP, ITEM_AMP);
  Self.Left := Rand(0, TILE_SIZE - ITEM_SIZE);
  Self.Angle := Rand(0, 360);
end;

destructor TItem.Destroy;
begin

  inherited;
end;

procedure TItem.SetActive(const Value: Boolean);
begin
  FActive := Value;
end;

{ TIBase }

function TIBase.Count: Integer;
begin
  Result := ITEMS_COUNT;
end;

constructor TIBase.Create;
begin

end;

destructor TIBase.Destroy;
begin

  inherited;
end;

{ TItems }

procedure TItems.Add(X, Y, ID: Integer);
var
  I: Integer;
begin
  if (Count <> 0) then
  for I := 0 to Count - 1 do
    if not Item[I].Active then
    begin
      Item[I].Create(X, Y, ID);
      Exit;
    end;
  SetLength(FItem, Count + 1);
  Item[Count - 1] := TItem.Create(X, Y, ID);
end;

function TItems.Count: Integer;
begin
  Result := System.Length(Item);
end;

constructor TItems.Create;
begin
  Base := TIBase.Create;
end;

destructor TItems.Destroy;
var
  I: Integer;
begin
  for I := 0 to Count - 1 do Item[I].Free;
  Base.Free;
  inherited;
end;

procedure TItems.Render;
var
  I: Integer;
begin
  for I := 0 to Count - 1 do
    if Item[I].Active then
    begin
      pRender2D.DrawTexture(Item[I].Texture,
        Point2((Item[I].Pos.X - MAP_LEFT) * TILE_SIZE + SCR_LEFT + Item[I].Left,
          (Item[I].Pos.Y - MAP_TOP) * TILE_SIZE + SCR_TOP +
          (TILE_SIZE - ITEM_SIZE) + Round(Item[I].Top) - ITEM_AMP),
        Point2(ITEM_SIZE, ITEM_SIZE), Item[I].Angle, EF_BLEND);
    end;
end;

procedure TItems.RenderItem(X, Y, I: Integer);
begin
  if (I < Base.Count) then pRender2D.DrawTexture(Item[I].Texture, Point2(X, Y), Point2(ITEM_SIZE, ITEM_SIZE));
end;

procedure TItems.SetBase(const Value: TIBase);
begin
  FBase := Value;
end;

procedure TItems.SetItem(const Value: TAItem);
begin
  FItem := Value;
end;

procedure TItems.Update;
var
  I: Integer;
begin
  for I := 0 to Count - 1 do
    if Item[I].Active then
    begin
      if Item[i].Dir then Item[i].Top := Item[i].Top + 0.2
        else Item[i].Top := Item[i].Top - 0.2;
      if (Item[i].Top >= ITEM_AMP) then Item[i].Dir := False;
      if (Item[i].Top <= -ITEM_AMP) then Item[i].Dir := True;
      Item[i].Angle := Item[i].Angle + 1;
    end;
end;

end.
